package interfaces.subpanel.summaryinfo.gui;

import interfaces.mainpanel.gui.TesisMainGUI;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.RowFilter;
import javax.swing.SwingConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableRowSorter;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;

import org.apache.commons.lang3.StringUtils;

import renderers.LabelRenderer;
import renderers.TextAreaRenderer;
import utils.ImagenesUtils;
import weka.gui.beans.ShadowBorder;

public class SummaryInfoGUI extends JPanel implements ActionListener, ListSelectionListener {

	private static final long serialVersionUID = 1L;

	private JButton clearDataButton;

	private JList listSummaryResults;

	private DefaultListModel listSummaryResultsModel;

	private ResultScenariesTable scenariesTable;

	private TableRowSorter<ResultScenariesTable> sorter;

	private JTable table;

	private JTextArea resultDetailsAreaClassify;

	private JTextArea resultDetailsAreaClustered;

	private JTextField filterText;

	private JComboBox headerTable;

	private String[] headersStrings = { " Scenarie ", " Type ", " Attribute ", " Cluster " };

	public SummaryInfoGUI(TesisMainGUI mainGUI) {

		super(new BorderLayout(5, 5));

		this.clearDataButton = new JButton("Clear Data", ImagenesUtils.createImageIcon(this.getClass(), "/dropBox.png"));
		this.clearDataButton.addActionListener(this);

		this.listSummaryResultsModel = new DefaultListModel();
		this.listSummaryResults = new JList(this.listSummaryResultsModel);
		this.listSummaryResults.setCellRenderer(new ResultSummaryCellRenderer(ImagenesUtils.createImageIcon(this.getClass(), "/check.png")));
		this.listSummaryResults.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		this.listSummaryResults.setSelectedIndex(0);
		this.listSummaryResults.addListSelectionListener(this);

		JScrollPane resultsPane = new JScrollPane(this.listSummaryResults);
		resultsPane.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Results: "), BorderFactory.createEmptyBorder(5, 5, 5, 5)),
				resultsPane.getBorder()));

		JPanel leftPanel = new JPanel(new BorderLayout(5, 5));
		leftPanel.add(this.clearDataButton, BorderLayout.PAGE_START);
		leftPanel.add(resultsPane, BorderLayout.CENTER);

		JPanel detailsPanel = new JPanel(new GridLayout(1, 2, 5, 5));

		this.resultDetailsAreaClassify = new JTextArea();
		this.resultDetailsAreaClassify.setBorder(new ShadowBorder(2, Color.LIGHT_GRAY));
		this.resultDetailsAreaClassify.setLineWrap(false);
		this.resultDetailsAreaClassify.setWrapStyleWord(false);
		this.resultDetailsAreaClassify.setEditable(false);
		this.resultDetailsAreaClassify.setMargin(new Insets(3, 3, 3, 3));

		JScrollPane panelDetailsArea = new JScrollPane(this.resultDetailsAreaClassify);

		panelDetailsArea.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createTitledBorder("Classifing Summary Result: "), BorderFactory.createEmptyBorder(5, 5, 5, 5)), panelDetailsArea.getBorder()));

		this.resultDetailsAreaClustered = new JTextArea();
		this.resultDetailsAreaClustered.setBorder(new ShadowBorder(2, Color.LIGHT_GRAY));
		this.resultDetailsAreaClustered.setLineWrap(false);
		this.resultDetailsAreaClustered.setWrapStyleWord(false);
		this.resultDetailsAreaClustered.setEditable(false);
		this.resultDetailsAreaClustered.setMargin(new Insets(3, 3, 3, 3));

		JScrollPane panelDetailsAreaClustered = new JScrollPane(this.resultDetailsAreaClustered);

		panelDetailsAreaClustered.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createTitledBorder("Clustering Summary Result: "), BorderFactory.createEmptyBorder(5, 5, 5, 5)), panelDetailsAreaClustered
				.getBorder()));

		detailsPanel.add(panelDetailsArea, 0);
		detailsPanel.add(panelDetailsAreaClustered, 1);

		this.scenariesTable = new ResultScenariesTable();
		this.sorter = new TableRowSorter<ResultScenariesTable>(this.scenariesTable);
		this.table = new JTable(this.scenariesTable);
		this.table.setFillsViewportHeight(true);
		this.table.setPreferredScrollableViewportSize(new Dimension(500, 70));
		this.table.getTableHeader().setPreferredSize(new Dimension(10, 27));
		this.table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

		TableColumnModel cmodel = this.table.getColumnModel();
		cmodel.getColumn(0).setCellRenderer(new TextAreaRenderer());
		cmodel.getColumn(1).setCellRenderer(new LabelRenderer());
		cmodel.getColumn(2).setCellRenderer(new LabelRenderer());
		cmodel.getColumn(3).setCellRenderer(new LabelRenderer());
		JScrollPane scrollPane = new JScrollPane(this.table);
		initColumnSizes();

		DocumentFilter filter = new UppercaseDocumentFilter();

		JPanel form = new JPanel(new BorderLayout(5, 5));
		JLabel l1 = new JLabel("Filter Text:", SwingConstants.TRAILING);
		this.filterText = new JTextField();
		((AbstractDocument) this.filterText.getDocument()).setDocumentFilter(filter);
		// Whenever filterText changes, invoke newFilter.
		this.filterText.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {
				newFilter();
			}

			public void insertUpdate(DocumentEvent e) {
				newFilter();
			}

			public void removeUpdate(DocumentEvent e) {
				newFilter();
			}
		});
		l1.setLabelFor(this.filterText);

		JPanel comboHeaderPanel = new JPanel(new BorderLayout(5, 5));
		this.headerTable = new JComboBox(this.headersStrings);
		this.headerTable.setSelectedIndex(0);
		this.headerTable.addActionListener(this);
		comboHeaderPanel.add(l1, BorderLayout.WEST);
		comboHeaderPanel.add(this.headerTable);

		form.add(comboHeaderPanel, BorderLayout.WEST);
		form.add(this.filterText, BorderLayout.CENTER);

		JPanel tableContainer = new JPanel(new BorderLayout(5, 5));
		tableContainer.add(scrollPane, BorderLayout.CENTER);
		tableContainer.add(form, BorderLayout.PAGE_END);
		tableContainer.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Scenaries: "), BorderFactory.createEmptyBorder(5, 5, 5, 5)),
				tableContainer.getBorder()));

		JPanel resultDetailPanel = new JPanel(new GridLayout(2, 1));
		resultDetailPanel.add(detailsPanel);
		resultDetailPanel.add(tableContainer);

		this.add(leftPanel, BorderLayout.WEST);
		this.add(resultDetailPanel, BorderLayout.CENTER);
	}

	/**
	 * Update the row filter regular expression from the expression in the text box.
	 */
	private void newFilter() {
		RowFilter<ResultScenariesTable, Object> rf = null;
		// If current expression doesn't parse, don't update.
		try {
			rf = RowFilter.regexFilter(this.filterText.getText(), this.headerTable.getSelectedIndex());
		} catch (java.util.regex.PatternSyntaxException e) {
			return;
		}
		this.sorter.setRowFilter(rf);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == this.clearDataButton) {
			this.clearData();
		}
	}

	private void clearData() {
		this.table.setRowSorter(null);
		this.scenariesTable.removeAllGenericScenaries();
		this.resultDetailsAreaClassify.setText(StringUtils.EMPTY);
		this.resultDetailsAreaClustered.setText(StringUtils.EMPTY);
		this.listSummaryResults.clearSelection();
	}

	public void resetData() {
		this.clearData();
		this.listSummaryResultsModel.removeAllElements();
	}

	public void valueChanged(ListSelectionEvent e) {
		if (e.getValueIsAdjusting() == false && this.listSummaryResults.getSelectedIndex() != -1) {

			// Limpio todo primero.
			this.scenariesTable.removeAllGenericScenaries();
			this.resultDetailsAreaClassify.setText(StringUtils.EMPTY);
			this.resultDetailsAreaClustered.setText(StringUtils.EMPTY);

			ResultSummaryEvaluation result = (ResultSummaryEvaluation) this.listSummaryResults.getSelectedValue();
			this.resultDetailsAreaClassify.setText(result.getResultClassifiedEval());
			this.resultDetailsAreaClassify.setCaretPosition(0);
			this.resultDetailsAreaClustered.setText(result.getResultClusteredEval());
			this.resultDetailsAreaClustered.setCaretPosition(0);

			// Agrego los escenarios funcionales a la tabla.
			this.scenariesTable.addAllGenericScenaries(result.getFunctionalityGenericScenaries());

			// Agrego los escenarios de calidad a la tabla.
			this.scenariesTable.addAllGenericScenaries(result.getQualityGenericScenaries());
			if (this.scenariesTable.isNotEmpty())
				this.table.setRowSorter(this.sorter);
			else
				this.table.setRowSorter(null);

		} else if (e.getValueIsAdjusting() == false && this.listSummaryResults.getSelectedIndex() == -1) {
			this.scenariesTable.removeAllGenericScenaries();
			this.resultDetailsAreaClassify.setText(StringUtils.EMPTY);
			this.resultDetailsAreaClustered.setText(StringUtils.EMPTY);
			if (this.scenariesTable.isNotEmpty())
				this.table.setRowSorter(this.sorter);
			else
				this.table.setRowSorter(null);
		}
	}

	private void initColumnSizes() {

		this.table.getColumnModel().getColumn(1).setMinWidth(120);
		this.table.getColumnModel().getColumn(1).setMaxWidth(120);
		this.table.getColumnModel().getColumn(2).setMinWidth(120);
		this.table.getColumnModel().getColumn(2).setMaxWidth(120);
		this.table.getColumnModel().getColumn(3).setMinWidth(80);
		this.table.getColumnModel().getColumn(3).setMaxWidth(80);

	}

	public void addNewResultSummaryEvaluation(ResultSummaryEvaluation resultSummaryEvaluation) {
		this.listSummaryResultsModel.addElement(resultSummaryEvaluation);
	}

	class UppercaseDocumentFilter extends DocumentFilter {

		// Override insertString method of DocumentFilter to make the text format
		// to uppercase.
		public void insertString(DocumentFilter.FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {

			fb.insertString(offset, text.toUpperCase(), attr);
		}

		// Override replace method of DocumentFilter to make the text format
		// to uppercase.
		public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {

			fb.replace(offset, length, text.toUpperCase(), attrs);
		}
	}
}
